package com.neusoft.neuiotms.dcam.fixed.service.impl;

import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.persistence.EntityNotFoundException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.neusoft.bizcore.activiti.model.WorkOrder;
import com.neusoft.bizcore.activiti.repository.WorkOrderRepository;
import com.neusoft.bizcore.auth.common.bean.RoleBean;
import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.auth.dto.AuthUserDTO;
import com.neusoft.bizcore.auth.model.AuthOganization;
import com.neusoft.bizcore.auth.repository.AuthOganizationRepository;
import com.neusoft.bizcore.auth.service.AuthUserService;
import com.neusoft.bizcore.web.bean.TreeBean;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.dto.result.ResultListDTO;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.bizcore.web.utils.ConsumeEasyPoiStyleImpl;
import com.neusoft.bizcore.web.utils.EasyPoiExcelUtil;
import com.neusoft.bizcore.web.utils.EasyPoiStylerColorImpl;
import com.neusoft.neuiotms.common.constant.AHConstants;
import com.neusoft.neuiotms.common.dto.DictionaryDTO;
import com.neusoft.neuiotms.common.service.DictionaryService;
import com.neusoft.neuiotms.dcam.anhui.util.PermUtils;
import com.neusoft.neuiotms.dcam.common.model.Location;
import com.neusoft.neuiotms.dcam.common.repository.LocationRepository;
import com.neusoft.neuiotms.dcam.common.service.LocationService;
import com.neusoft.neuiotms.dcam.constant.DCAMConsts;
import com.neusoft.neuiotms.dcam.fixed.converter.AssetConverter;
import com.neusoft.neuiotms.dcam.fixed.converter.AssetLifeCycleConverter;
import com.neusoft.neuiotms.dcam.fixed.dto.AssetDTO;
import com.neusoft.neuiotms.dcam.fixed.dto.AssetLifeCycleDTO;
import com.neusoft.neuiotms.dcam.fixed.dto.WarehouseRecordDTO;
import com.neusoft.neuiotms.dcam.fixed.model.Asset;
import com.neusoft.neuiotms.dcam.fixed.model.AssetLifeCycle;
import com.neusoft.neuiotms.dcam.fixed.model.AssetType;
import com.neusoft.neuiotms.dcam.fixed.model.MachinePartsBind;
import com.neusoft.neuiotms.dcam.fixed.repository.AssetLifeCycleRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.AssetRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.AssetTypeRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.MachinePartsBindRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.StorehouseRepository;
import com.neusoft.neuiotms.dcam.fixed.service.AssetCodeRuleService;
import com.neusoft.neuiotms.dcam.fixed.service.AssetService;
import com.neusoft.neuiotms.dcam.fixed.service.StorehouseService;
import com.neusoft.neuiotms.dcam.fixed.service.WarehouseRecordService;
import com.neusoft.neuiotms.dcam.fixed.util.AhHelper;
import com.neusoft.neuiotms.dcam.fixed.util.SendingMessage;
import com.neusoft.neuiotms.dcam.fixed.vo.AssetImportKjVO;
import com.neusoft.neuiotms.dcam.fixed.vo.AssetImportSlVO;
import com.neusoft.neuiotms.dcam.fixed.vo.AssetImportVO;
import com.neusoft.neuiotms.dcam.fixed.vo.ConsumptionExportVO;
import com.neusoft.neuiotms.dcam.fixed.vo.ConsumptionImportVO;
import com.neusoft.neuiotms.dcam.util.CreateLogMessage;
import com.neusoft.neuiotms.dcam.util.OperationEnum;
import com.neusoft.neuiotms.dcam.workflow.model.WorkOrderDeposit;
import com.neusoft.neuiotms.dcam.workflow.repository.WorkOrderDepositRepository;
import com.neusoft.neuiotms.micro.auth.AuthMicroService;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@Transactional
public class AssetServiceImpl implements AssetService {

    @Autowired
    private AssetConverter assetConverter;
    @Autowired
    private AssetRepository assetRepository;
    @Autowired
    private LocationRepository locationRepository;
    @Autowired
    private LocationService locationService;
    @Autowired
    private AuthMicroService authMicroService;
    @Autowired
    private AssetTypeRepository assetTypeRepository;
    @Autowired
    private SendingMessage sendingMessage;
    @Autowired
    private AssetConverter assetConventer;
    @Autowired
    private AssetCodeRuleService assetCodeRuleService;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private StorehouseRepository storehouseRepository;
    @Autowired
    private AuthUserService authUserService;
    @Autowired
    private AuthOganizationRepository authOganizationRepository;
    @Autowired
    private StorehouseService storehouseService;
    @Autowired
    private WarehouseRecordService warehouseRecordService;
    @Autowired
    private WorkOrderDepositRepository workOrderDepositRepository;
    @Autowired
    private AssetLifeCycleConverter assetLifeCycleConverter;
    @Autowired
    private AssetLifeCycleRepository assetLifeCycleRepository;
    @Autowired
    private MachinePartsBindRepository machinePartsBindRepository;
    @Autowired
    private WorkOrderRepository workOrderRepository;
    @Autowired
    private CreateLogMessage createLogMessage;

    @Override
    public List<AssetDTO> index(final Searchable searchable) {
        final List<Asset> models = this.assetRepository.search(searchable);
        return this.assetConverter.toListDTO(models);
    }

    @Override
    public long count(final Searchable searchable) {
        return this.assetRepository.count(searchable);
    }

    @Override
    public Page<AssetDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<Asset> models = this.assetRepository.search(pageable, searchable);
        final Page<AssetDTO> dtos = this.assetConverter.toPageDTO(models);
        return dtos;
    }

    @Override
    public Page<AssetDTO> search(final Pageable pageable, final Searchable searchable, final UserBean userBean) {
        final Searchable resultSearchable = this.commonSearchable(searchable, userBean);
        final Page<Asset> models = this.assetRepository.search(pageable, resultSearchable);
        final Page<AssetDTO> dtos = this.assetConverter.toPageDTO(models);
        return dtos;
    }

    @Override
    public Page<AssetDTO> searchBind(final Pageable pageable, final Searchable searchable, final UserBean userBean) {
        final String bindTypeCode = searchable.getStrValue("bindTypeCode");
        final String bindCode = searchable.getStrValue("bindCode");
        List<MachinePartsBind> partsBindList;
        if ("1190299010000".equals(bindTypeCode)) { //机器配件
            partsBindList = this.machinePartsBindRepository.findByPartsCodeAndStatus(bindCode, "1");
        } else {
            //查询资产绑定的机器配件
            partsBindList = this.machinePartsBindRepository.findByBindCodeAndStatus(bindCode, "1");
        }
        if ((partsBindList != null) && (partsBindList.size() > 0)) {
            final Searchable resultSearchable = this.commonSearchable(searchable, userBean);
            final String[] assetCodes =
                    partsBindList.stream().map(MachinePartsBind::getPartsCode).collect(Collectors.toList())
                            .toArray(new String[1]);
            resultSearchable.put("codes", assetCodes);
            final Page<Asset> models = this.assetRepository.search(pageable, resultSearchable);
            final Page<AssetDTO> dtos = this.assetConverter.toPageDTO(models);
            return dtos;
        } else {
            final List<Asset> listResult = new ArrayList<>();
            final Page<Asset> models = new PageImpl<>(listResult, pageable, 0);
            final Page<AssetDTO> dtos = this.assetConverter.toPageDTO(models);
            return dtos;
        }
    }

    @Override
    public Page<AssetDTO> searchNoBind(final Pageable pageable, final Searchable searchable, final UserBean userBean) {
        //查询绑定的机器配件
        final Searchable resultSearchable = this.commonSearchable(searchable, userBean);
        final List<MachinePartsBind> partsBindList = this.machinePartsBindRepository.findByStatus("1");
        if ((partsBindList != null) && (partsBindList.size() > 0)) {
            final String[] assetCodes =
                    partsBindList.stream().map(MachinePartsBind::getPartsCode).collect(Collectors.toList())
                            .toArray(new String[1]);
            resultSearchable.put("notExitsCodes", assetCodes); //去除已绑定的设备
        }
        final Page<Asset> models = this.assetRepository.search(pageable, resultSearchable);
        final Page<AssetDTO> dtos = this.assetConverter.toPageDTO(models);
        return dtos;
    }

    /**
     * 根据角色、权限、所属组织，组合查询条件
     *
     * @param searchable
     * @param userBean
     * @return
     */
    private Searchable commonSearchable(final Searchable searchable, final UserBean userBean) {
        if (searchable.hasKey("categories") && "3".equals(searchable.getStrValue("categories"))) {
            if (PermUtils.isSLAssetOwnerAdmin(userBean) || PermUtils.isAdmin(userBean)
                    || PermUtils.isKJAssetAdmin(userBean) || PermUtils.isKJAdministrationPrincipal(userBean)) {
                searchable.put("managementOrgCodeIsnull", true);
            } else {
                final List<String> orgCodeList = userBean.getOrgs();
                searchable.put("managementOrgCode", orgCodeList.toArray(new String[orgCodeList.size()]));
            }
        } else {
            // 科技数据
            if (AHConstants.BELONG_KJ_CODE.equals(searchable.getStrValue("belongs"))) {
                // 科技公司-资产管理员查询所有科技的资产，多角色的情况下，资产管理员权限最大
                if (PermUtils.isKJAssetAdmin(userBean)) {
                    searchable.put("belongs", AHConstants.BELONG_KJ_CODE);
                }
                // 部门级别的角色，查询部门级别的
                else if (PermUtils.isKJDeptAssetAdmin(userBean) || PermUtils.isKJDeptPrincipal(userBean)) {
                    final List<String> orgCodeList = userBean.getOrgs();
                    searchable.put("managementOrgCode", orgCodeList.toArray(new String[orgCodeList.size()]));
                }
                // 个人用户，只能查看自己的资产。（纯个人用户，理论上前端菜单不会看到资产台账的菜单）
                else if (PermUtils.isOnlyKJSystemUser(userBean)) {
                    searchable.put("managementUserCode", userBean.getUsername());
                }
            } // 总行数据
            else {
                if (PermUtils.isSLAssetOwnerAdmin(userBean) || PermUtils.isSLAssetOwnerPrincipal(userBean)) {
                    searchable.put("belongs", AHConstants.BELONG_SL_CODE);
                } // 部门级别的角色，查询部门级别的
                else if (PermUtils.isSLDeptAssetAdmin(userBean) || PermUtils.isSLDeptAssetPrincipal(userBean)) {
                    //TODO: 刘婷这个角色涉及到省行和科技公司的数据交叉，具体处理方法需要跟客户确定
                    final List<String> orgCodeList = userBean.getOrgs();
                    searchable.put("managementOrgCode", orgCodeList.toArray(new String[orgCodeList.size()]));
                }
            }
        }
        return searchable;
    }

    @Override
    public Page<AssetDTO> mySearch(final Pageable pageable, final Searchable searchable, final UserBean userBean) {
        searchable.put("managementUserCode", userBean.getUsername());
        final Page<Asset> models = this.assetRepository.search(pageable, searchable);
        final Page<AssetDTO> dtos = this.assetConverter.toPageDTO(models);
        return dtos;
    }

    @Override
    public AssetDTO create(final AssetDTO dto, final HttpServletRequest request, UserBean user) {

        Asset model = this.assetConverter.toModel(dto);
        if ("3".equals(dto.getCategories())) {
            final Asset xhAsset = this.assetRepository
                    .findTopBySmallTypeCodeAndBelongsAndManagementOrgCodeOrderByCreateTimeDesc(dto.getSmallTypeCode(),
                            dto.getBelongs(),
                            null);
            if (null != xhAsset) {
                xhAsset.setAmount(xhAsset.getAmount() + model.getAmount());
                model = xhAsset;
            }
        }
        this.assetRepository.save(model);
        if (AhHelper.isSl(model.getBelongs())) {
            String extra = "资产编码：" + model.getCode();
            if ((null == request) && (null == user)) {
                extra = "通过工单创建，" + extra;
            }
            if (null == user) {
                user = new UserBean();
                user.setUsername("内部系统");
            }
            this.createLogMessage.sendMsgToLogServer(user, request, OperationEnum.CREATE.toString(),
                    extra);
        }
        return this.assetConverter.toDTO(model);
    }

    @Override
    public AssetDTO details(final Long id) {

        final Asset model;
        try {
            model = this.assetRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.assetConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id, final HttpServletRequest request, UserBean user) {
        final Asset model = this.assetRepository.findById(id).orElse(null);
        if (null != model) {
            if (AhHelper.isSl(model.getBelongs())) {
                this.createLogMessage.sendMsgToLogServer(user, request, OperationEnum.DELETE.toString(),
                        "资产编码：" + model.getCode());
            }
            this.assetRepository.delete(model);
        }
    }

    @Override
    public AssetDTO update(final Long id, final AssetDTO dto) {

        Asset model;
        try {
            model = this.assetRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        dto.setId(model.getId());
        model = this.assetConverter.toModel(dto);
        this.assetRepository.save(model);

        return this.assetConverter.toDTO(model);
    }

    @Override
    public Workbook template(final String belongs) {
        final List<AssetImportVO> list = new ArrayList<>();
        final Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("资产导入模板", "资产导入模板", ExcelType.XSSF),
                AHConstants.BELONG_KJ_CODE.equals(belongs) ? AssetImportKjVO.class : AssetImportSlVO.class, list);
        // 设置资产大、中、小分类级联数据
        this.getTypeCascade(workbook, belongs);
        // 设置部门和用户的级联数据
        this.getOrgUserCascade(workbook, belongs);
        // 设置位置和状态的约束数据
        final List<Map<String, Object>> constraint = this.getConstraint(belongs);
        EasyPoiExcelUtil.setConstraint(constraint, workbook, DCAMConsts.ASSET_START_CONSTRAINT_ROW,
                DCAMConsts.ASSET_CONSTRAINT_ROW);
        return workbook;
    }

    @Override
    public Workbook export(final Searchable searchable, final Pageable pageable, final String belongs,
            final String categories, final String id) {

        searchable.put("belongs", belongs);
        searchable.put("categories", categories);
        if (!"all".equals(id)) {
            final String idString = id.substring(0, id.length() - 1);
            final String[] idArray = idString.split("-");
            searchable.put("id", idArray);
        }
        final List<Asset> models = this.assetRepository.search(searchable);

        final List<AssetImportVO> list =
                models.stream().map(it -> this.assetConventer.toVO(it)).collect(Collectors.toList());

        // 拼接位置
        final List<TreeBean> locTree = this.locationService.tree(belongs);
        final List<String> constraintList = new ArrayList<>();
        for (final TreeBean b : locTree) {
            constraintList.add(b.getTitle() + DCAMConsts.DICTIONARY_SPLITOR + b.getCode());
            this.joinLocationTree(constraintList, b, b.getTitle());
        }
        // 拼接状态
        final List<DictionaryDTO> assetStatuses = this.dictionaryService.findByDictionaryType("assetStatus");
        list.forEach(vo -> {
            if (StringUtils.isNotEmpty(vo.getLocationName())) {
                final Optional<String> optional =
                        constraintList.stream().filter(it -> it.indexOf("_" + vo.getLocationName()) > -1).findFirst();
                if (optional.isPresent()) {
                    vo.setLocationName(optional.get());
                }
            }
            final Optional<DictionaryDTO> statusDict =
                    assetStatuses.stream().filter(it -> it.getCode().equals(vo.getStatus())).findFirst();
            if (statusDict.isPresent()) {
                vo.setStatus(statusDict.get().getText() + DCAMConsts.DICTIONARY_SPLITOR + statusDict.get().getCode());
            }
        });

        final ExportParams param = new ExportParams("资产导出", "资产导出", ExcelType.XSSF);
        param.setStyle(EasyPoiStylerColorImpl.class);

        final Workbook workbook = ExcelExportUtil.exportExcel(param,
                AHConstants.BELONG_KJ_CODE.equals(belongs) ? AssetImportKjVO.class : AssetImportSlVO.class, list);

        // 设置资产大、中、小分类级联数据
        this.getTypeCascade(workbook, belongs);
        // 设置部门和用户的级联数据
        this.getOrgUserCascade(workbook, belongs);
        // 设置位置和状态的约束数据
        final List<Map<String, Object>> constraint = this.getConstraint(belongs);
        EasyPoiExcelUtil.setConstraint(constraint, workbook, DCAMConsts.ASSET_START_CONSTRAINT_ROW,
                DCAMConsts.ASSET_CONSTRAINT_ROW);

        return workbook;

    }

    /**
     * 设置位置和状态的约束数据
     *
     * @param belongs
     * @return
     */
    private List<Map<String, Object>> getConstraint(final String belongs) {
        final List<Map<String, Object>> constraint = new ArrayList<>();
        // 总行：资产状态7，资产位置12
        // 科技：资产状态7，资产位置14
        //        final int[] constraintColumns = {7, 14 };

        final int[] constraintColumns = AHConstants.BELONG_KJ_CODE.equals(belongs)
                ? new int[] {7, 14 } : new int[] {7, 12 };

        for (final int element : constraintColumns) {
            final List<String> constraintList = new ArrayList<>();
            switch (element) {
            case 12:
            case 14:
                final List<TreeBean> locTree = this.locationService.tree(belongs);
                for (final TreeBean b : locTree) {
                    constraintList.add(b.getTitle() + DCAMConsts.DICTIONARY_SPLITOR + b.getCode());
                    this.joinLocationTree(constraintList, b, b.getTitle());
                }
                break;
            case 7:
                final List<DictionaryDTO> assetStatuses = this.dictionaryService.findByDictionaryType("assetStatus");
                assetStatuses.forEach(l -> {
                    constraintList.add(l.getText() + DCAMConsts.DICTIONARY_SPLITOR + l.getCode());
                });
                break;
            default:
                break;
            }
            if (!constraintList.isEmpty()) {
                final Map<String, Object> map = new HashMap<>();
                map.put("list", constraintList);
                map.put("col", element);
                constraint.add(map);
            }
        }
        return constraint;
    }

    /**
     * 设置资产分类的级联
     *
     * @param workbook
     * @param belongs
     */
    private void getTypeCascade(final Workbook workbook, final String belongs) {

        // 所有的分类
        final List<AssetType> types = this.assetTypeRepository.findAll();

        // 大分类
        List<AssetType> first = Lists.newArrayList();
        if (AHConstants.BELONG_KJ_CODE.equals(belongs)) {
            first = types.stream()
                    .filter(t -> (null != t.getParent()) && AHConstants.BELONG_KJ_CODE.equals(t.getParent().getCode()))
                    .collect(Collectors.toList());
        } else if (AHConstants.BELONG_SL_CODE.equals(belongs)) {
            first = types.stream()
                    .filter(t -> (null != t.getParent()) && AHConstants.BELONG_SL_CODE.equals(t.getParent().getCode()))
                    .collect(Collectors.toList());
        }
        // 大分类编码
        final List<String> firstCodes = first.stream().map(AssetType::getCode).collect(Collectors.toList());

        // 中分类
        final List<AssetType> second = types.stream().filter(t -> {
            return (t.getParent() != null) && firstCodes.contains(t.getParent().getCode());
        }).collect(Collectors.toList());
        final List<String> secondCodes = second.stream().map(AssetType::getCode).collect(Collectors.toList());

        // 小分类
        final List<AssetType> third = types.stream().filter(t -> {
            return (t.getParent() != null) && secondCodes.contains(t.getParent().getCode());
        }).collect(Collectors.toList());

        final List<String> allParent = new ArrayList<>();
        final List<String> mainParent = new ArrayList<>();

        // 大分类与中分类的映射关系；中分类与小分类的映射关系
        final Map<String, List<String>> children = new HashMap<>();
        first.forEach(t -> {
            final String code = t.getName() + DCAMConsts.DICTIONARY_SPLITOR + t.getCode();
            mainParent.add(code);
            allParent.add(code);
            final List<String> currentCodechild = new ArrayList<>();
            second.stream().filter(a -> {
                return (a.getParent() != null) && a.getParent().getCode().equals(t.getCode());
            }).map(s -> {
                return s.getName() + DCAMConsts.DICTIONARY_SPLITOR + s.getCode();
            }).forEach(currentCodechild::add);
            children.put(code, currentCodechild);
        });

        second.forEach(t -> {
            final String code = t.getName() + DCAMConsts.DICTIONARY_SPLITOR + t.getCode();
            allParent.add(code);
            final List<String> currentCodechild = new ArrayList<>();
            third.stream().filter(a -> {
                return (a.getParent() != null) && a.getParent().getCode().equals(t.getCode());
            }).map(s -> {
                return s.getName() + DCAMConsts.DICTIONARY_SPLITOR + s.getCode();
            }).forEach(currentCodechild::add);
            children.put(code, currentCodechild);
        });

        //        third.forEach(t -> {
        //            final String code = t.getName() + DCAMConsts.DICTIONARY_SPLITOR + t.getCode();
        //            allParent.add(code);
        //            final List<String> currentCodeChild = new ArrayList<>();
        //            currentCodeChild.add(StringUtils.isEmpty(t.getMeasureUnit()) ? "" : t.getMeasureUnit());
        //            children.put(code, currentCodeChild);
        //        });

        // 大分类列
        final int col1 = 3;
        // 中分类列
        final int col2 = 4;
        // 小分类列
        final int col3 = 5;
        // 小分类列
        //        final int col19 = AHConstants.BELONG_KJ_CODE.equals(belongs) ? 19 : 17;

        final ArrayList<Integer> columns =
                Lists.newArrayList(col1, col2, col3);
        EasyPoiExcelUtil.cascade(workbook, mainParent, allParent, children, columns, 0,
                1,
                DCAMConsts.ASSET_CONSTRAINT_ROW);

    }

    /**
     * 设置部门用不的级联
     *
     * @param workbook
     * @param belongs
     */
    private void getOrgUserCascade(final Workbook workbook, final String belongs) {

        final List<AuthOganization> orgList = this.authOganizationRepository.findAll();
        final List<AuthOganization> belongsOrgList;
        if (AHConstants.BELONG_KJ_CODE.equals(belongs)) {
            belongsOrgList = orgList.stream()
                    .filter(it -> it.getCode().startsWith(AHConstants.BELONG_KJ_CODE))
                    .collect(Collectors.toList());
        } else {
            belongsOrgList = orgList.stream()
                    .filter(it -> !it.getCode().startsWith(AHConstants.BELONG_KJ_CODE)
                            || it.getCode().equals("kj"))
                    .collect(Collectors.toList());
        }

        final List<String> allParent = new ArrayList<>();
        final List<String> mainParent = new ArrayList<>();
        final Map<String, List<String>> cascadeMap = new HashMap<>();

        belongsOrgList.forEach(t -> {
            final String value = t.getName() + DCAMConsts.DICTIONARY_SPLITOR + t.getCode();
            mainParent.add(value);
            allParent.add(value);

            final List<String> children = new ArrayList<>();

            final String orgCode = t.getCode();

            // 省联社下载模板中，科技中心部门可以看到下面所有二级部门的用户
            if ("kj".equalsIgnoreCase(orgCode) && AHConstants.BELONG_SL_CODE.equals(belongs)) {
                final AuthOganization kjRoot = this.authOganizationRepository.findByCode("kj");
                final List<AuthOganization> subNodes = this.authOganizationRepository.findByParent(kjRoot);
                subNodes.add(kjRoot);
                final List<String> orgCodes = subNodes.stream().map(org -> org.getCode()).collect(Collectors.toList());
                final Searchable searchable = new Searchable();
                searchable.put("orgCodes", orgCodes);
                final List<AuthUserDTO> users = this.authUserService.findAll(searchable);
                users.stream().map(it -> it.getName()).forEach(children::add);
            } else {
                final AuthOganization org = this.authOganizationRepository.findByCode(orgCode);
                org.getUsers().stream().map(it -> it.getName()).forEach(children::add);
            }
            //            final ResultDTO<Map<String, Object>> orgResult = this.authMicroService.orgInfoByCode(orgCode);
            //            final Map<String, Object> orgInfo = orgResult.getData();
            //            final List<Map<String, Object>> users = (List<Map<String, Object>>) orgInfo.get("users");
            //            users.stream().map(it -> String.valueOf(it.get("name"))).forEach(children::add);
            cascadeMap.put(value, children);
        });

        // 使用部门属性的列号
        final int col1 = AHConstants.BELONG_KJ_CODE.equals(belongs) ? 22 : 20;
        // 使用人属性的列号
        final int col2 = AHConstants.BELONG_KJ_CODE.equals(belongs) ? 23 : 21;
        final ArrayList<Integer> columns =
                Lists.newArrayList(col1, col2);

        EasyPoiExcelUtil.cascade(workbook, mainParent, allParent, cascadeMap, columns, 0,
                1,
                DCAMConsts.ASSET_CONSTRAINT_ROW);

    }

    @Override
    public void upload(final InputStream fileStream, final String belongs, final String categories,
            final String username) {
        final String title = "资产导入结果";
        final StringBuilder errorMsg = new StringBuilder();
        final ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        params.setNeedVerify(true);

        final Class<?> clazz =
                AHConstants.BELONG_KJ_CODE.equals(belongs) ? AssetImportKjVO.class : AssetImportSlVO.class;
        try {
            final ExcelImportResult<AssetImportVO> result =
                    ExcelImportUtil.importExcelMore(fileStream, clazz, params);
            if (result.getList().isEmpty() && result.getFailList().isEmpty()) {
                this.sendingMessage.SendImportResultToNotice(title, username, "上传数据为空");
                return;
            }
            if (result.isVerifyFail()) {
                final List<AssetImportVO> failList = result.getFailList();
                failList.forEach(l -> {
                    errorMsg.append("第" + (l.getRowNum() + 1) + "行," + l.getErrorMsg() + "! \n");
                });
            }
            if (errorMsg.length() > 0) {
                AssetServiceImpl.log.error(errorMsg.toString());
                this.sendingMessage.SendImportResultToNotice(title, username, errorMsg.toString());
                return;
            }

            //取全部的组织机构和用户
            List<Map<String, Object>> users = new ArrayList<>();
            final ResultListDTO<Map<String, Object>> userList = this.authMicroService.allUsers();
            if (userList.isSuccess()) {
                users = userList.getData();
            }
            List<Map<String, Object>> orgs = new ArrayList<>();
            final ResultListDTO<Map<String, Object>> orgList = this.authMicroService.allOrganizations();
            if (orgList.isSuccess()) {
                orgs = orgList.getData();
            }

            final List<Asset> models = new ArrayList<>();
            final List<AssetImportVO> saveList = result.getList();
            for (int i = 0; i < saveList.size(); i++) {
                final AssetImportVO asset = saveList.get(i);
                asset.setBelongs(belongs);
                asset.setCategories(categories);
                final Asset model = this.assetConventer.toModel(asset);
                // 小类型
                if (!StringUtils.isEmpty(asset.getAssetTypeName())
                        && asset.getAssetTypeName().contains(DCAMConsts.DICTIONARY_SPLITOR)) {
                    final String[] types = asset.getAssetTypeName().split(DCAMConsts.DICTIONARY_SPLITOR);
                    try {
                        final AssetType type = this.assetTypeRepository.findByCode(types[1]);
                        model.setSmallTypeCode(type.getCode());
                        model.setSmallTypeName(type.getName());

                        final AssetType middleType = type.getParent();
                        if (null != middleType) {
                            model.setMiddleTypeCode(middleType.getCode());
                            model.setMiddleTypeName(middleType.getName());

                            final AssetType bigType = middleType.getParent();

                            if (null != bigType) {
                                model.setBigTypeCode(bigType.getCode());
                                model.setBigTypeName(bigType.getName());
                            }
                        }

                    } catch (final EntityNotFoundException e) {
                        AssetServiceImpl.log.error("第" + (i + 1) + "行," + "资产类型不存在");
                        this.sendingMessage.SendImportResultToNotice(title, username, "第" + (i + 1) + "行," + "资产类型不存在");
                        return;
                    }
                }
                // 位置
                if (!StringUtils.isEmpty(asset.getLocationName())
                        && asset.getLocationName().contains(DCAMConsts.DICTIONARY_SPLITOR)) {

                    final int idx = asset.getLocationName().lastIndexOf(DCAMConsts.DICTIONARY_SPLITOR);

                    //                    final String[] locations = asset.getLocationName().split(DCAMConsts.DICTIONARY_SPLITOR);
                    try {
                        final Location location =
                                this.locationRepository.findByCode(asset.getLocationName().substring(idx + 1));
                        if (null != location) {
                            model.setLocation(location.getCode());
                            model.setLocationName(location.getName());
                        }
                    } catch (final EntityNotFoundException e) {
                        AssetServiceImpl.log.error("第" + (i + 1) + "行," + "位置不存在");
                        this.sendingMessage.SendImportResultToNotice(title, username, "第" + (i + 1) + "行," + "位置不存在");
                        return;
                    }
                }
                //使用部门
                if (!StringUtils.isEmpty(asset.getOrg()) && asset.getOrg().contains(DCAMConsts.DICTIONARY_SPLITOR)) {
                    //                    final String[] orgSegmengs = asset.getOrg().split(DCAMConsts.DICTIONARY_SPLITOR);
                    final int idx = asset.getOrg().indexOf(DCAMConsts.DICTIONARY_SPLITOR);
                    final String code = asset.getOrg().substring(idx + 1);
                    Boolean hasOrg = false;
                    for (final Map<String, Object> t : orgs) {
                        if (t.get("code").equals(code)) {
                            model.setManagementOrgCode(String.valueOf(t.get("code")));
                            model.setManagementOrgName(String.valueOf(t.get("name")));
                            hasOrg = true;
                            break;
                        }
                    }
                    if (!hasOrg) {
                        AssetServiceImpl.log.error("第" + (i + 1) + "行," + "使用部门不存在");
                        this.sendingMessage.SendImportResultToNotice(title, username, "第" + (i + 1) + "行," + "使用部门不存在");
                        return;
                    }
                }
                // 使用人
                if (!StringUtils.isEmpty(asset.getUser()) && asset.getUser().contains(DCAMConsts.DICTIONARY_SPLITOR)) {
                    final int idx = asset.getUser().indexOf(DCAMConsts.DICTIONARY_SPLITOR);
                    final String user = asset.getUser().substring(idx + 1);
                    Boolean hasUser = false;
                    for (final Map<String, Object> t : users) {
                        if (t.get("username").equals(user)) {
                            model.setManagementUserCode(String.valueOf(t.get("username")));
                            model.setManagementUserName(String.valueOf(t.get("name")));
                            hasUser = true;
                            break;
                        }
                    }

                    if (!hasUser) {
                        AssetServiceImpl.log.error("第" + (i + 1) + "行," + "使用人不存在或使用部门不包含该使用人");
                        this.sendingMessage.SendImportResultToNotice(title, username,
                                "第" + (i + 1) + "行," + "使用人不存在或使用部门不包含该使用人");
                        return;
                    }
                } else if (!StringUtils.isEmpty(asset.getUser())) {
                    final Optional<Map<String, Object>> user = users.stream()
                            .filter(u -> asset.getUser().equals(String.valueOf(u.get("name")))).findFirst();
                    if (user.isPresent()) {
                        model.setManagementUserCode(String.valueOf(user.get().get("username")));
                        model.setManagementUserName(String.valueOf(user.get().get("name")));
                    }
                }

                // 状态
                if (!StringUtils.isEmpty(asset.getStatus())
                        && asset.getStatus().contains(DCAMConsts.DICTIONARY_SPLITOR)) {
                    final int idx = asset.getStatus().indexOf(DCAMConsts.DICTIONARY_SPLITOR);
                    final String status = asset.getStatus().substring(idx + 1);
                    model.setStatus(status);
                }
                //资产编码
                if (!StringUtils.isEmpty(asset.getCode())) {
                    model.setCode(asset.getCode());
                } else {
                    String code = this.assetCodeRuleService.generateAssetCode(model.getBelongs(),
                            model.getSmallTypeCode(),
                            model.getPurchaseDate(), model.getCategories());
                    while (this.assetRepository.countByCode(code) > 0) {
                        code = this.assetCodeRuleService.generateAssetCode(model.getBelongs(),
                                model.getSmallTypeCode(),
                                model.getPurchaseDate(), model.getCategories());
                    }
                    model.setCode(code);

                    // 分割资产
                    if (model.getAmount() > 1) {
                        final double singleMoney = new BigDecimal(model.getMoney() / model.getAmount())
                                .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                        final int amount = model.getAmount();
                        model.setAmount(1);
                        model.setMoney(singleMoney);
                        models.add(model);
                        for (int j = 1; j < amount; j++) {
                            final Asset cloned = model.clone();
                            String code1 = this.assetCodeRuleService.generateAssetCode(cloned.getBelongs(),
                                    cloned.getSmallTypeCode(),
                                    cloned.getPurchaseDate(), cloned.getCategories());
                            while (this.assetRepository.countByCode(code1) > 0) {
                                code1 = this.assetCodeRuleService.generateAssetCode(model.getBelongs(),
                                        model.getSmallTypeCode(),
                                        model.getPurchaseDate(), model.getCategories());
                            }
                            cloned.setCode(code1);
                            models.add(cloned);
                        }
                    }
                }
                models.add(model);
            }
            //if (!models.isEmpty() && (errorMsg.length() == 0)) {
            if (!models.isEmpty()) {
                this.assetRepository.saveAll(models);
                this.sendingMessage.SendImportResultToNotice(title, username, "资产上传成功");
            }

        } catch (final Exception e) {
            AssetServiceImpl.log.error("上传失败", e);
            this.sendingMessage.SendImportResultToNotice(title, username, "上传失败" + e.getMessage());
            throw new UnitedException(e.getMessage(), new Object[] {});
        }

    }

    @Override
    public long assetTotalStats(final Searchable searchable, final UserBean userBean) {
        if (PermUtils.isAdmin(userBean)) {// 管理员
            return this.assetRepository.count(searchable);
        } else if (PermUtils.isOnlyKJSystemUser(userBean)) {// 科技公司系统用户只能查询自己名下的资产
            searchable.put("managementUserCode", userBean.getUsername());
            return this.assetRepository.count(searchable);
        } else if (PermUtils.isKJAssetAdmin(userBean)) {// 科技公司资产管理员
            return this.assetRepository.count(searchable);
        } else if (PermUtils.isKJDeptAssetAdmin(userBean) || PermUtils.isKJDeptPrincipal(userBean)
                || PermUtils.isKJAdministrationPrincipal(userBean)) {// 科技公司部门负责人、科技公司综合管理部、综合管理部负责人
            if (userBean.getOrgs().size() > 0) {
                searchable.put("managementOrgCode", userBean.getOrgs().get(0));
                return this.assetRepository.count(searchable);
            } else {
                return 0;
            }
        } else if (PermUtils.isSLAssetBuyer(userBean) || PermUtils.isSLAssetOwnerAdmin(userBean)
                || PermUtils.isSLAssetOwnerPrincipal(userBean)) {//总行采购员、总行资产归口管理员、总行资产归口负责人
            return this.assetRepository.count(searchable);
        } else if (PermUtils.isSLDeptAssetAdmin(userBean) || PermUtils.isSLDeptAssetPrincipal(userBean)) {//总行部门资产管理员、总行部门资产负责人
            if (userBean.getOrgs().size() > 0) {
                searchable.put("managementOrgCode", userBean.getOrgs().get(0));
                return this.assetRepository.count(searchable);
            } else {
                return 0;
            }
        }
        return 0;
    }

    @Override
    public void updateLocked(final List<String> codes, final Boolean locked) {

        if ((codes != null) && (codes.size() > 0)) {
            final List<Asset> assets = this.assetRepository.findByCodeIn(codes);
            if (null != assets) {
                assets.forEach(l -> {
                    l.setLocked(locked);
                });
                this.assetRepository.saveAll(assets);
            }
        }

    }

    @Override
    public void updateStatus(final List<String> codes, final String status) {

        if ((codes != null) && (codes.size() > 0)) {
            final List<Asset> assets = this.assetRepository.findByCodeIn(codes);
            if (null != assets) {
                assets.forEach(l -> {
                    l.setStatus(status);
                });
                this.assetRepository.saveAll(assets);
            }
        }

    }

    /**
     * 将位置树，生成A-B-C_C编码，格式的结构，这样的话，在下载模板中，位置列可以把所有位置都显示出来
     *
     * @param results
     * @param parent
     * @param parentPrefix
     */
    private void joinLocationTree(final List<String> results, final TreeBean parent, final String parentPrefix) {
        if (parent.getChildren().size() > 0) {
            for (final TreeBean b : parent.getChildren()) {
                final String tmp = parentPrefix + "-" + b.getTitle() + DCAMConsts.DICTIONARY_SPLITOR + b.getCode();
                results.add(tmp);
                this.joinLocationTree(results, b, parentPrefix + "-" + b.getTitle());
            }
        }
    }

    @Override
    public Workbook xhTemplate(final String belongs) {
        final List<ConsumptionImportVO> list = new ArrayList<>();
        final Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("消耗品导入模板", "消耗品导入模板", ExcelType.XSSF),
                ConsumptionImportVO.class, list);
        // 级联数据
        this.getXhTypeCascade(workbook, belongs);
        // 设置消耗品分类和仓库位置约束
        final List<Map<String, Object>> constraint = this.getXhTypeAndLocationConstraint();
        EasyPoiExcelUtil.setConstraint(constraint, workbook, DCAMConsts.ASSET_START_CONSTRAINT_ROW,
                DCAMConsts.ASSET_CONSTRAINT_ROW);
        return workbook;
    }

    /**
     * 设置资产分类的级联
     *
     * @param workbook
     * @param belongs
     */
    private void getXhTypeCascade(final Workbook workbook, final String belongs) {

        // 所有的分类
        final List<AssetType> types = this.assetTypeRepository.findAll();
        // 消耗品分类
        final List<AssetType> typeList = types.stream()
                .filter(t -> (null != t.getParent()) && "xh".equals(t.getParent().getCode()))
                .collect(Collectors.toList());

        final List<String> allParent = new ArrayList<>();
        final List<String> mainParent = new ArrayList<>();

        // 大分类与中分类的映射关系；中分类与小分类的映射关系
        final Map<String, List<String>> children = new HashMap<>();
        typeList.forEach(t -> {
            final String code = t.getName() + DCAMConsts.DICTIONARY_SPLITOR + t.getCode();
            mainParent.add(code);
            allParent.add(code);
            final List<String> currentCodeChild = new ArrayList<>();
            currentCodeChild.add(StringUtils.isEmpty(t.getMeasureUnit()) ? "" : t.getMeasureUnit());
            children.put(code, currentCodeChild);
        });

        // 分类列
        final int col1 = 1;
        // 计量单位列
        final int col2 = 7;

        final ArrayList<Integer> columns =
                Lists.newArrayList(col1, col2);
        EasyPoiExcelUtil.cascade(workbook, mainParent, allParent, children, columns, 0,
                1,
                DCAMConsts.ASSET_CONSTRAINT_ROW);

    }

    /**
     * 设置消耗品分类和仓库位置约束
     *
     * @return
     */
    private List<Map<String, Object>> getXhTypeAndLocationConstraint() {
        final List<Map<String, Object>> constraint = new ArrayList<>();
        //        final int typeColumNum = 1;
        final int locationColumNum = 5;

        //        // 所有的分类
        //        final List<AssetType> types = this.assetTypeRepository.findAll();
        //        // 消耗品分类
        //        final List<AssetType> typeList = types.stream()
        //                .filter(t -> (null != t.getParent()) && "xh".equals(t.getParent().getCode()))
        //                .collect(Collectors.toList());
        //
        //        final List<String> constraintList = typeList.stream()
        //                .map(it -> it.getName() + DCAMConsts.DICTIONARY_SPLITOR + it.getCode()).collect(Collectors.toList());
        //
        //        final Map<String, Object> map = new HashMap<>();
        //        map.put("list", constraintList);
        //        map.put("col", typeColumNum);
        //        constraint.add(map);

        // 所有仓库
        final List<Location> locations =
                this.storehouseRepository.findAll().stream().map(it -> it.getLocation()).collect(Collectors.toList());
        final List<String> locationConstraintList = locations.stream()
                .map(it -> it.getName() + DCAMConsts.DICTIONARY_SPLITOR + it.getCode()).collect(Collectors.toList());
        final Map<String, Object> mapLocation = new HashMap<>();
        mapLocation.put("list", locationConstraintList);
        mapLocation.put("col", locationColumNum);
        constraint.add(mapLocation);

        return constraint;
    }

    @Override
    public Workbook xhExport(final Searchable searchable, final Pageable pageable, final String belongs,
            final String categories, final String id) {
        searchable.put("belongs", belongs);
        searchable.put("categories", categories);
        if (!"all".equals(id)) {
            final String idString = id.substring(0, id.length() - 1);
            final String[] idArray = idString.split("-");
            searchable.put("id", idArray);
        }
        final List<Asset> models = this.assetRepository.search(searchable);

        final List<ConsumptionImportVO> list =
                models.stream().map(it -> this.assetConventer.toConsumptionVO(it)).collect(Collectors.toList());

        final ExportParams param = new ExportParams("消耗品导出", "消耗品导出", ExcelType.XSSF);
        param.setStyle(EasyPoiStylerColorImpl.class);
        return ExcelExportUtil.exportExcel(param, ConsumptionImportVO.class, list);

    }

    @Override
    public void xhUpload(final InputStream fileStream, final String belongs, final String categories,
            final String username) {
        final List<WarehouseRecordDTO> records = new ArrayList<>();

        final String title = "消耗品导入结果";
        final StringBuilder errorMsg = new StringBuilder();
        final ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        params.setNeedVerify(true);

        final Class<?> clazz = ConsumptionImportVO.class;
        try {
            final ExcelImportResult<ConsumptionImportVO> result =
                    ExcelImportUtil.importExcelMore(fileStream, clazz, params);
            if (result.getList().isEmpty() && result.getFailList().isEmpty()) {
                this.sendingMessage.SendImportResultToNotice(title, username, "上传数据为空");
                return;
            }
            if (result.isVerifyFail()) {
                final List<ConsumptionImportVO> failList = result.getFailList();
                failList.forEach(l -> {
                    errorMsg.append("第" + (l.getRowNum() + 1) + "行," + l.getErrorMsg() + "! \n");
                });
            }
            if (errorMsg.length() > 0) {
                AssetServiceImpl.log.error(errorMsg.toString());
                this.sendingMessage.SendImportResultToNotice(title, username, errorMsg.toString());
                return;
            }

            final List<Asset> models = new ArrayList<>();
            final List<ConsumptionImportVO> saveList = result.getList();
            for (int i = 0; i < saveList.size(); i++) {
                final ConsumptionImportVO asset = saveList.get(i);
                asset.setBelongs(belongs);
                asset.setCategories(categories);
                final Asset model = this.assetConventer.toModel(asset);
                // 小类型
                if (!StringUtils.isEmpty(asset.getAssetTypeName())
                        && asset.getAssetTypeName().contains(DCAMConsts.DICTIONARY_SPLITOR)) {
                    final String[] types = asset.getAssetTypeName().split(DCAMConsts.DICTIONARY_SPLITOR);
                    try {
                        final AssetType type = this.assetTypeRepository.findByCode(types[1]);
                        model.setSmallTypeCode(type.getCode());
                        model.setSmallTypeName(type.getName());
                        model.setMeasureUnit(type.getMeasureUnit());

                        final AssetType middleType = type.getParent();
                        if (null != middleType) {
                            model.setMiddleTypeCode(middleType.getCode());
                            model.setMiddleTypeName(middleType.getName());

                            final AssetType bigType = middleType.getParent();

                            if (null != bigType) {
                                model.setBigTypeCode(bigType.getCode());
                                model.setBigTypeName(bigType.getName());
                            }
                        }

                    } catch (final EntityNotFoundException e) {
                        AssetServiceImpl.log.error("第" + (i + 1) + "行," + "消耗品类型不存在");
                        this.sendingMessage.SendImportResultToNotice(title, username,
                                "第" + (i + 1) + "行," + "消耗品类型不存在");
                        return;
                    }
                }
                //资产编码
                model.setCode(UUID.randomUUID().toString());
                models.add(model);

                //生成消耗品入库记录
                if (this.storehouseService.LocationIsStorehouse(model.getLocation())) {
                    records.add(WarehouseRecordDTO.builder()
                            .name(model.getName())
                            .specifications(model.getSpecifications())
                            .brand(model.getBrand())
                            .smallTypeName(model.getSmallTypeName())
                            .smallTypeCode(model.getSmallTypeName()).contractNo(model.getContractNo())
                            .contractName(model.getContractName()).amount(model.getAmount())
                            .location(model.getLocation())
                            .locationName(model.getLocationName()).type("1").build());
                }
            }
            //if (!models.isEmpty() && (errorMsg.length() == 0)) {
            if (!models.isEmpty()) {

                final Multimap<String, Asset> map = ArrayListMultimap.create();
                models.forEach(m -> {
                    map.put(m.getSmallTypeCode(), m);
                });

                final List<Asset> updateList = Lists.newArrayList();
                map.keySet().forEach(k -> {
                    final Asset xhAsset = this.assetRepository
                            .findTopBySmallTypeCodeAndBelongsAndManagementOrgCodeOrderByCreateTimeDesc(k, belongs,
                                    null);

                    if (null != xhAsset) {
                        int amount = 0;
                        for (final Asset a : map.get(k)) {
                            amount += a.getAmount();
                        }
                        xhAsset.setAmount(xhAsset.getAmount() + amount);
                        final Collection<Asset> assets = map.get(k);
                        xhAsset.setMeasureUnit(assets.stream().findAny().get().getMeasureUnit());
                        updateList.add(xhAsset);
                    } else {
                        final Collection<Asset> assets = map.get(k);
                        final Iterator<Asset> it = assets.iterator();
                        final Asset s = it.next();
                        int amount = s.getAmount();
                        while (it.hasNext()) {
                            final Asset a = it.next();
                            amount += a.getAmount();
                        }
                        s.setAmount(amount);
                        updateList.add(s);
                    }
                });

                this.assetRepository.saveAll(updateList);
                this.sendingMessage.SendImportResultToNotice(title, username, "消耗品上传成功");
            }

            if (!records.isEmpty()) {
                this.warehouseRecordService.batchCreate(records);
            }

        } catch (final Exception e) {
            AssetServiceImpl.log.error("上传失败", e);
            this.sendingMessage.SendImportResultToNotice(title, username, "上传失败" + e.getMessage());
            throw new UnitedException(e.getMessage(), new Object[] {});
        }

    }

    @Override
    public void batchDelete(final List<Long> ids) {
        for (final Long id : ids) {
            this.assetRepository.deleteById(id);
        }
    }

    @Override
    public void updateAseetCardForSL(final long id, final String cardNo) {
        final Asset model;
        try {
            model = this.assetRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        model.setOriginalCode(cardNo);
        this.assetRepository.save(model);
    }

    @Override
    public Map<String, Object> userRole(final UserBean user) {
        boolean isShow = true;
        final List<RoleBean> roles = user.getRoles();
        for (final RoleBean roleBean : roles) {
            if ("kjDeptAssetAdmin".equals(roleBean.getRole())) {
                isShow = false;
            }
        }
        final Map<String, Object> retMap = new HashMap<>();
        retMap.put("show", isShow);
        return retMap;
    }

    @Override
    public Workbook exportWorkbook(final Searchable searchable, final String belongs,
            final String categories, final UserBean user) {
        final List<Map<String, Object>> sheetsList = new ArrayList<>();
        final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        //查询全部消耗品
        searchable.put("belongs", belongs);
        searchable.put("categories", categories);
        final List<Asset> models = this.assetRepository.search(searchable);

        for (final Asset asset : models) {
            //循环查询每个消耗品已有的生命周期
            final List<AssetLifeCycle> AssetLifeCycle =
                    this.assetLifeCycleRepository.findByCodeOrderByCreateTimeDesc(asset.getCode());
            final List<AssetLifeCycleDTO> lifeCycleList = this.assetLifeCycleConverter.toListDTO(AssetLifeCycle);
            //            final List<AssetLifeCycleDTO> lifeCycleList =
            //                    this.assetLifeCycleService.detailByCode(asset.getCode(), user);
            final List<ConsumptionExportVO> list = new ArrayList<>();
            for (final AssetLifeCycleDTO lifeCycle : lifeCycleList) {
                final int rk = lifeCycle.getContent().indexOf("入库");
                final int ly = lifeCycle.getContent().indexOf("领用");
                if ((rk < 0) && (ly < 0)) {
                    continue;
                }
                //根据工单号查询结存表的信息
                final List<WorkOrderDeposit> depositList =
                        this.workOrderDepositRepository.findByWorkOrderNum(lifeCycle.getWorkNum());
                final ConsumptionExportVO consumption = new ConsumptionExportVO();
                depositList.stream().forEach(deposit -> {
                    if (deposit.getSmallTypeCode().equals(asset.getSmallTypeCode())) {
                        consumption.setBalance(deposit.getQuantity());
                    }
                });
                consumption.setName(asset.getSmallTypeName());
                consumption.setYear(format.format(lifeCycle.getCreateTime()).substring(2, 4));
                consumption.setMonth(format.format(lifeCycle.getCreateTime()).substring(4, 6));
                consumption.setDay(format.format(lifeCycle.getCreateTime()).substring(6));
                if (lifeCycle.getContent().indexOf("入库") > 0) {
                    consumption.setPurchase(
                            Integer.parseInt(
                                    lifeCycle.getContent().substring(lifeCycle.getContent().indexOf("为") + 1)));
                }
                if (lifeCycle.getContent().indexOf("领用") > 0) {
                    consumption.setReceive(this.getQuantity(lifeCycle.getContent()));
                }

                if (lifeCycle.getContent().indexOf("入库") > 0) {
                    consumption.setOperType("入库");
                }
                if (lifeCycle.getContent().indexOf("领用") > 0) {
                    consumption.setOperType("领用");
                }
                final WorkOrder model = this.workOrderRepository.findByWorkOrderNum(lifeCycle.getWorkNum());
                consumption.setReceiveUser(model.getApplyUserName());

                list.add(consumption);
            }
            final ExportParams empExportParams = new ExportParams();
            empExportParams.setTitle("安徽省农村信用社联社科技信息中心办公用品领用登记簿");
            empExportParams.setSecondTitle(
                    "品   名：" + asset.getSmallTypeName()
                            + "                                      "
                            + "单位："
                            + asset.getMeasureUnit() + "                                      "
                            + "数量：" + asset.getAmount() + "                                        ");
            empExportParams.setHeaderColor(HSSFColor.HSSFColorPredefined.DARK_RED.getIndex());
            empExportParams.setSheetName(asset.getSmallTypeName());
            empExportParams.setStyle(ConsumeEasyPoiStyleImpl.class);
            empExportParams.setReadonly(false);
            final Map<String, Object> empExportMap = new HashMap<>();
            empExportMap.put("title", empExportParams);
            empExportMap.put("entity", ConsumptionExportVO.class);
            empExportMap.put("data", list);
            sheetsList.add(empExportMap);
        }
        return ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);

    }

    @Override
    public Workbook chooseExportWorkbook(final Searchable searchable, final String belongs,
            final String categories, final Long ids, final UserBean user) {
        final List<Map<String, Object>> sheetsList = new ArrayList<>();
        final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        //查询全部消耗品
        searchable.put("belongs", belongs);
        searchable.put("categories", categories);
        searchable.put("ids", ids);
        final List<Asset> models = this.assetRepository.search(searchable);

        for (final Asset asset : models) {
            //循环查询每个消耗品已有的生命周期
            final List<AssetLifeCycle> AssetLifeCycle =
                    this.assetLifeCycleRepository.findByCodeOrderByCreateTimeDesc(asset.getCode());
            final List<AssetLifeCycleDTO> lifeCycleList = this.assetLifeCycleConverter.toListDTO(AssetLifeCycle);
            //            final List<AssetLifeCycleDTO> lifeCycleList =
            //                    this.assetLifeCycleService.detailByCode(asset.getCode(), user);
            final List<ConsumptionExportVO> list = new ArrayList<>();
            for (final AssetLifeCycleDTO lifeCycle : lifeCycleList) {
                final int rk = lifeCycle.getContent().indexOf("入库");
                final int ly = lifeCycle.getContent().indexOf("领用");
                if ((rk < 0) && (ly < 0)) {
                    continue;
                }
                //根据工单号查询结存表的信息
                final List<WorkOrderDeposit> depositList =
                        this.workOrderDepositRepository.findByWorkOrderNum(lifeCycle.getWorkNum());
                final ConsumptionExportVO consumption = new ConsumptionExportVO();
                depositList.stream().forEach(deposit -> {
                    if (deposit.getSmallTypeCode().equals(asset.getSmallTypeCode())) {
                        consumption.setBalance(deposit.getQuantity());
                    }
                });
                consumption.setName(asset.getSmallTypeName());
                consumption.setYear(format.format(lifeCycle.getCreateTime()).substring(2, 4));
                consumption.setMonth(format.format(lifeCycle.getCreateTime()).substring(4, 6));
                consumption.setDay(format.format(lifeCycle.getCreateTime()).substring(6));
                if (lifeCycle.getContent().indexOf("入库") > 0) {
                    consumption.setPurchase(
                            Integer.parseInt(
                                    lifeCycle.getContent().substring(lifeCycle.getContent().indexOf("为") + 1)));
                }
                if (lifeCycle.getContent().indexOf("领用") > 0) {
                    consumption.setReceive(this.getQuantity(lifeCycle.getContent()));
                }

                consumption.setReceiveUser(lifeCycle.getUserName());

                list.add(consumption);
            }
            final ExportParams empExportParams = new ExportParams();
            empExportParams.setTitle("安徽省农村信用社联社科技信息中心办公用品领用登记簿");
            empExportParams.setSecondTitle(
                    "品   名：" + asset.getSmallTypeName()
                            + "                                      "
                            + "单位："
                            + asset.getMeasureUnit() + "                                      "
                            + "数量：" + asset.getAmount() + "                                        ");
            empExportParams.setHeaderColor(HSSFColor.HSSFColorPredefined.DARK_RED.getIndex());
            empExportParams.setSheetName(asset.getSmallTypeName());
            empExportParams.setStyle(ConsumeEasyPoiStyleImpl.class);
            empExportParams.setReadonly(true);
            final Map<String, Object> empExportMap = new HashMap<>();
            empExportMap.put("title", empExportParams);
            empExportMap.put("entity", ConsumptionExportVO.class);
            empExportMap.put("data", list);
            sheetsList.add(empExportMap);
        }
        return ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);

    }

    private int getQuantity(final String content) {
        final String[] arr = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
        final List<String> list = Arrays.asList(arr);
        final int index = content.indexOf("为");
        String num = null;
        for (int i = index + 1; i < content.length(); i++) {
            if (!list.contains(String.valueOf(content.charAt(i)))) {
                num = content.substring(index + 1, i);
                break;
            }
        }
        return num == null ? 0 : Integer.parseInt(num);
    }

    @Override
    public AssetDTO detailsByCode(final String code) {

        final Asset model;
        try {
            model = this.assetRepository.findByCode(code);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {code });
        }

        return this.assetConverter.toDTO(model);
    }

    @Override
    public void markLabelPrinted(List<Long> assetIdList) {
        final List<Asset> assetList = this.assetRepository.findByIdIn(assetIdList);
        assetList.forEach(it -> it.setLabelPrinted(true));
        this.assetRepository.saveAll(assetList);
    }

}
